﻿using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

namespace ApiData.Web.Controllers
{
    public class AppController : BaseController
    {
        private readonly IMemoryCache cache;

        public AppController(SqlSugarClient context, IMemoryCache cache) : base(context)
        {
            this.cache = cache;
        }

        public IActionResult Index()
        {
            ViewBag.UserCode = LoginUser.code;
            ViewBag.Name = LoginUser.name;
            ViewBag.Domain = Request.Scheme + "://" + Request.Host.Value;
            return View();
        }
        // 获取所有app
        public IActionResult AxGetApps()
        {
            var list = context.Queryable<Model.application>().Where(x => x.userid == LoginUser.id).ToList();
            return Json(Result.SuccessData(list));
        }
        // 获取app所有table
        public IActionResult AxGetTabs(int appid)
        {
            var list = context.Queryable<Model.tables>().Where(x => x.applicationid == appid).ToList();
            return Json(Result.SuccessData(list));
        }
        // 分页查询table数据
        public IActionResult AxGetDataPage(int tableid, string page = "1", string size = "15")
        {
            var tab = context.Queryable<Model.tables>().First(x => x.id == tableid);
            var data = Logic.Page.Execute(tab, page, size);
            var list = new
            {
                count = data.count,
                data = data.data,
                structure = Logic.Select.Structure(tab).data
            };
            return Json(Result.SuccessData(list));
        }
        // 添加应用
        public IActionResult AxEditApp(Model.application app)
        {
            var count = 0;
            if (app.id != 0)
            {
                // 获取当前操作数据
                var model = context.Queryable<Model.application>().First(x => x.id == app.id && x.userid == LoginUser.id);
                // 如果数据库的appid和用户提交的appid不一致，则表示用户需要修改appid
                if (model.appid != app.appid)
                {
                    // 使用新的appid查找应用
                    var hm = context.Queryable<Model.application>().First(x => x.appid == app.appid && x.userid == LoginUser.id);
                    if (hm != null) return Json(Result.Fail("已存在此appid的应用"));
                }
                // 设置修改值
                model.appid = app.appid;
                model.name = app.name;
                model.note = app.note;
                // 修改数据
                count = context.Updateable<Model.application>(model).ExecuteCommand();
            }
            else
            {
                // 使用新的appid查找应用
                var model = context.Queryable<Model.application>().First(x => x.appid == app.appid && x.userid == LoginUser.id);
                if (model != null) return Json(Result.Fail("已存在此appid的应用"));
                // 设置数据
                model = app;
                model.userid = LoginUser.id;
                // 新增应用
                count = context.Insertable<Model.application>(app).ExecuteCommand();
            }

            if (count > 0) return Json(Result.Success());
            else return Json(Result.Fail());
        }
        // 添加数据表
        public IActionResult AxEditTable(int appid, Model.tables table)
        {
            var app = context.Queryable<Model.application>().First(x => x.id == appid && x.userid == LoginUser.id);
            if (app == null) return Json(Result.Fail("不存在此应用"));

            var count = 0;
            if (table.id != 0)
            {
                // 获取当前操作数据
                var model = context.Queryable<Model.tables>().First(x => x.applicationid == appid && x.id == table.id);
                // 如果数据库的code和用户提交的code不一致，则表示用户需要修改appid
                if (model.code != table.code)
                {
                    // 使用新的code查找应用
                    var hm = context.Queryable<Model.tables>().First(x => x.applicationid == appid && x.code == table.code);
                    if (hm != null) return Json(Result.Fail("已存在此表"));
                }
                // 设置修改值
                model.code = table.code;
                model.name = table.name;
                model.note = table.note;
                // 修改数据
                count = context.Updateable<Model.tables>(model).ExecuteCommand();
            }
            else
            {
                // 使用新的appid查找应用
                var model = context.Queryable<Model.tables>().First(x => x.applicationid == appid && x.code == table.code);
                if (model != null) return Json(Result.Fail("已存在此表"));
                // 设置数据
                model = table;
                model.applicationid = appid;
                model.code = table.code;
                model.name = table.name;
                model.count = 0;
                model.note = table.note;
                model.structure = "";
                // 新建数据库json文件，并设定文件路径
                var dirpath = Directory.GetCurrentDirectory();
                var filepath = $"/data/{LoginUser.code}/{app.appid}/";
                var filename = $"{table.code}.json";
                if (!Directory.Exists(dirpath + filepath)) Directory.CreateDirectory(dirpath + filepath);
                var real = dirpath + filepath + $"{table.code}.json";
                using (var fs = new FileStream(real, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
                {
                    using (var sw = new StreamWriter(fs))
                    {
                        sw.WriteLine("[]");
                        sw.Close();
                    }
                    fs.Close();
                }
                model.jsondata = filepath + filename;
                // 新增表格
                count = context.Insertable<Model.tables>(model).ExecuteCommand();
            }

            if (count > 0) return Json(Result.Success());
            else return Json(Result.Fail());
        }
        // 保存表结构
        public IActionResult AxSaveTabStruc(int tableid, List<Model.Dto.Structure> list)
        {
            var tab = context.Queryable<Model.tables>().First(x => x.id == tableid);
            if (tab == null) return Json(Result.Fail("不存在此表"));
            var app = context.Queryable<Model.application>().First(x => x.id == tab.applicationid && x.userid == LoginUser.id);
            if (app == null) return Json(Result.Fail("应用错误，拒绝操作"));

            var stru = "";
            foreach (var item in list)
                stru += $"{item.name}-{item.type}-{item.defaultvalue}-{item.des}\r\n";
            tab.structure = stru;
            int count = context.Updateable<Model.tables>(tab).ExecuteCommand();

            if (count > 0) return Json(Result.Success());
            else return Json(Result.Fail());
        }
        // 删除App
        public IActionResult AxDelApp(int appid)
        {
            var model = context.Queryable<Model.application>()
                .Includes(x => x.tables).First(x => x.id == appid && x.userid == LoginUser.id);
            if (model == null) return Json(Result.Fail("找不到要删除的App"));
            if (model.tables.Count > 0) return Json(Result.Fail("此应用不为空"));

            int count = context.Deleteable(model).ExecuteCommand();
            if (count > 0) return Json(Result.Success());
            else return Json(Result.Fail());
        }
        // 删除表
        public IActionResult AxDelTable(int tableid)
        {
            var tab = context.Queryable<Model.tables>().First(x => x.id == tableid);
            if (tab == null) return Json(Result.Fail("不存在此数据表"));
            var app = context.Queryable<Model.application>().First(x => x.id == tab.applicationid && x.userid == LoginUser.id);
            if (app == null) return Json(Result.Fail("不存在此应用"));

            int count = context.Deleteable(tab).ExecuteCommand();
            if (count > 0)
            {
                var real = Directory.GetCurrentDirectory() + tab.jsondata;
                System.IO.File.Delete(real);
                return Json(Result.Success());
            }
            else return Json(Result.Fail());
        }
        // 增加一条table数据
        public IActionResult AxAddData(int tableid, List<Model.Dto.Structure> list)
        {
            var tab = context.Queryable<Model.tables>().First(x => x.id == tableid);
            if (tab == null) return Json(Result.Fail("不存在此数据表"));
            var app = context.Queryable<Model.application>().First(x => x.id == tab.applicationid && x.userid == LoginUser.id);
            if (app == null) return Json(Result.Fail("不存在此应用"));

            Dictionary<string, string> dic = new Dictionary<string, string>();
            foreach (var item in list)
                dic.Add(item.name, item.value);
            return Json(Logic.Insert.Execute(tab, dic));
        }
        // 删除一条table数据
        public IActionResult AxDelData(int tableid, int index)
        {
            var tab = context.Queryable<Model.tables>().First(x => x.id == tableid);
            if (tab == null) return Json(Result.Fail("不存在此数据表"));
            var app = context.Queryable<Model.application>().First(x => x.id == tab.applicationid && x.userid == LoginUser.id);
            if (app == null) return Json(Result.Fail("不存在此应用"));

            return Json(Logic.Delete.Execute(tab, index));
        }
        // 修改一条table数据
        public IActionResult AxEditData(int tableid, int index, List<Model.Dto.Structure> list)
        {
            var tab = context.Queryable<Model.tables>().First(x => x.id == tableid);
            if (tab == null) return Json(Result.Fail("不存在此数据表"));
            var app = context.Queryable<Model.application>().First(x => x.id == tab.applicationid && x.userid == LoginUser.id);
            if (app == null) return Json(Result.Fail("不存在此应用"));

            Dictionary<string, string> dic = new Dictionary<string, string>();
            foreach (var item in list)
                dic.Add(item.name, item.value);
            return Json(Logic.Update.Execute(tab, dic, index));
        }
    }
}
